#!/usr/bin/env python
# -*- coding:utf-8 -*-

import threading
from concurrent import futures
import logging,time 


# ThreadPoolExecutor例子
"""
# 输出格式定义
FORMAT = '%(asctime)-15s\t [%(processName)s:%(threadName)s,%(process)d:%(thread)8d] %(message)s'
logging.basicConfig(level=logging.INFO,format=FORMAT)

def worker(n):
    logging.info('begin to work{}'.format(n))
    time.sleep(5)
    logging.info('finished{}'.format(n))

# 创建线程池,池的容量为3
executor = futures.ThreadPoolExecutor(max_workers=3)
fs = []
for i in range(3):
    future = executor.submit(worker,i)
    fs.append(future)

for i in range(3,6):
    future = executor.submit(worker,i)
    fs.append(future)

while True:
    time.sleep(2)
    logging.info(threading.enumerate())

    flag = True
    for f in fs: # 判断是否还有未完成的任务
        logging.info(f.done())
        flag = flag and f.done()
        # if not flag: # 注释if
        #   break
    print('-'*30)

    if flag: 
        executor.shutdown() # 清理池,池中线程全部杀掉.
        logging.info(threading.enumerate())
        break
    
# 线程池一旦创建了线程,就不需要频繁清除.
"""




# ProcessPoolExecutor对象
# 方法一样,就是使用多进程完成.
"""
# 输出格式定义
FORMAT = '%(asctime)-15s\t [%(processName)s:%(threadName)s, %(process)d:%(thread)8d] %(message)s'
logging.basicConfig(level=logging.INFO,format=FORMAT)

def worker(n):
    logging.info('begin to work{}'.format(n))
    time.sleep(5)
    logging.info('finished{}'.format(n))

if __name__=='__main__':
    # 创建进程池,池的容量为3.
    executor = futures.ProcessPoolExecutor(max_workers=3)
    fs = []
    for i in range(3):
        future = executor.submit(worker,i)
        fs.append(future)

    for i in range(3,6):
        future = executor.submit(worker,i)
        fs.append(future)

    while True:
        time.sleep(2)
        logging.info(threading.enumerate())

        flag = True
        for f in fs: # 判断是否还有未完成的任务.
            logging.info(f.done())
            flag = flag and f.done()
            # if not flag: 
            #   break

        print('-'*30)

        if flag:
            executor.shutdown()  # 清理池,除非不用,不用频繁清理池.
            logging.info(threading.enumerate()) # 多进程时看主线程已经没有必要了.
            break
"""




# 使用上下文管理改造上面的例子,增加返回计算的结果

# 输出格式定义
FORMAT = '%(asctime)-15s\t [%(processName)s:%(threadName)s,%(process)d:%(thread)8d] %(message)s'
logging.basicConfig(level=logging.INFO,format=FORMAT)

def worker(n):
    logging.info('begin to work{}'.format(n))
    time.sleep(5)
    logging.info('finished{}'.format(n))
    return n + 100 # 返回结果

if __name__=='__main__':
    # 创建进程池,池的容量为3
    executor = futures.ProcessPoolExecutor(max_workers=3)

    with executor: #上下文
        fs = []
        for i in range(3):
            future = executor.submit(worker,i)
            fs.append(future)

        for i in range(3,6):
            future = executor.submit(worker,i)
            fs.append(future)

        while True:
            time.sleep(2)
            logging.info(threading.enumerate())

            flag = True
            for f in fs: #判断是否还有未完成的任务
                logging.info(f.done())
                flag = flag and f.done()
                if f.done(): # 如果做完了,看效果
                    logging.info("result = {}".format(f.result()))
                # if not flag: #注释if
                #   break

            print('-'*30)
            if flag: break
    
    # executor.shutdown() #上下文清理了资源
    logging.info('======end=====')
    logging.info(threading.enumerate()) #多进程时看主线程已经没必要了.

    